//
//  UIViews.swift
//  JXBaseTools
//
//  Created by godox on 2021/11/30.
//

import UIKit


extension JX where Base: UIView {
    
    /// 裁剪圆角
    /// - Parameters:
    ///   - direction: 裁剪的上下左右的边角设置
    ///   - cornerRadius: 圆弧数值
    public func clipRectCorner(direction: UIRectCorner, cornerRadius: CGFloat) {
        let cornerSize = CGSize(width:cornerRadius, height:cornerRadius)
        let maskPath = UIBezierPath(roundedRect: base.bounds, byRoundingCorners: direction, cornerRadii: cornerSize)
        let maskLayer = CAShapeLayer()
        maskLayer.frame = base.bounds
        maskLayer.path = maskPath.cgPath
        base.layer.addSublayer(maskLayer)
        base.layer.mask = maskLayer
    }
    
    
    public func removeAllSubviews(){
        let views = base.subviews
        for  i in views {
            i.removeFromSuperview()
        }
    }
    
    @discardableResult
    public func setViewCornerRadius(_ cornerRadius: CGFloat) -> Base {
        base.clipsToBounds = true
        base.layer.cornerRadius = cornerRadius
        return base
    }
    
    @discardableResult
    public func setViewBorderColor(_ borderColor: CGColor)-> Base {
        base.layer.borderColor = borderColor
        return base
    }
    @discardableResult
    public func setViewBorderWidth(_ borderWidth: CGFloat)-> Base {
        base.layer.borderWidth = borderWidth
        return base
    }
    
    /// 添加渐变色
    /// - Parameters:
    ///   - frame: color layer of frame
    ///   - view: add color layer to superView
    ///   - colors: array colors
    ///   - locations: ranage 0 - 1   count == colors.count
    ///   - statrPoint: statr
    ///   - endPoint: end
    public func setBackgroundColors(_ frame: CGRect, at view: UIView, _ colors: [UIColor], _ locations: [NSNumber], _ statrPoint: CGPoint, _ endPoint: CGPoint){
        let gradientLayer = CAGradientLayer()
        gradientLayer.frame = frame
        view.layer.addSublayer(gradientLayer)
        gradientLayer.colors = colors
        gradientLayer.locations = locations
        gradientLayer.startPoint = statrPoint
        gradientLayer.endPoint = endPoint
    }
    
    /// 添加虚线边框
    /// - Parameters:
    ///   - width: 虚线的宽度
    ///   - length: 虚线长度
    ///   - space: 虚线间距
    ///   - cornerRadius: view圆角
    ///   - color: 虚线颜色
    public func drawBoardDottedLine(width: CGFloat,
                                    length: CGFloat,
                                    space: CGFloat,
                                    cornerRadius: CGFloat,
                                    color: UIColor){
        base.layer.cornerRadius = cornerRadius
        let borderLayer =  CAShapeLayer()
        borderLayer.bounds = base.bounds
        
        borderLayer.position = CGPoint(x: base.bounds.midX, y: base.bounds.midY);
        borderLayer.path = UIBezierPath(roundedRect: borderLayer.bounds, cornerRadius: cornerRadius).cgPath
        borderLayer.lineWidth = width / UIScreen.main.scale
        
        //虚线边框---小边框的长度
        borderLayer.lineDashPattern = [length,space]  as [NSNumber]? //前边是虚线的长度，后边是虚线之间空隙的长度
        borderLayer.lineDashPhase = 0.1
        //实线边框
        
        borderLayer.fillColor = UIColor.clear.cgColor
        borderLayer.strokeColor = color.cgColor
        base.layer.addSublayer(borderLayer)
    }
    
    /// 获取特定位置的颜色
    ///
    /// - parameter at: 位置
    ///
    /// - returns: 颜色
    public func pickColor(at position: CGPoint) -> UIColor? {
        
        // 用来存放目标像素值
        var pixel = [UInt8](repeatElement(0, count: 4))
        // 颜色空间为 RGB，这决定了输出颜色的编码是 RGB 还是其他（比如 YUV）
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        // 设置位图颜色分布为 RGBA
        let bitmapInfo = CGImageAlphaInfo.premultipliedLast.rawValue
        guard let context = CGContext(data: &pixel, width: 1, height: 1, bitsPerComponent: 8, bytesPerRow: 4, space: colorSpace, bitmapInfo: bitmapInfo) else {
            return nil
        }
        // 设置 context 原点偏移为目标位置所有坐标
        context.translateBy(x: -position.x, y: -position.y)
        // 将图像渲染到 context 中
        base.layer.render(in: context)
        
        return UIColor(red: CGFloat(pixel[0]) / 255.0,
                       green: CGFloat(pixel[1]) / 255.0,
                       blue: CGFloat(pixel[2]) / 255.0,
                       alpha: CGFloat(pixel[3]) / 255.0)
    }
    
    
    /// 获取多个点的颜色值
    /// - Parameter positions: 点的位置
    /// - Returns: 颜色
    public func blendColors(at positions: [CGPoint]) -> UIColor? {
        // 计算平均颜色的初始值
        var totalRed: CGFloat = 0.0
        var totalGreen: CGFloat = 0.0
        var totalBlue: CGFloat = 0.0
        
        // 颜色空间为 RGB，这决定了输出颜色的编码是 RGB 还是其他（比如 YUV）
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        // 设置位图颜色分布为 RGBA
        let bitmapInfo = CGImageAlphaInfo.premultipliedLast.rawValue
        
        var removeCount: Int = 0
        // 遍历每个位置
        for position in positions {
            // 用于存放当前位置的像素值
            var pixel = [UInt8](repeatElement(0, count: 4))
            
            guard let context = CGContext(data: &pixel, width: 1, height: 1, bitsPerComponent: 8, bytesPerRow: 4, space: colorSpace, bitmapInfo: bitmapInfo) else {
                return nil
            }
            
            // 设置 context 原点偏移为当前位置的坐标
            context.translateBy(x: -position.x, y: -position.y)
            
            // 将图像渲染到 context 中
            base.layer.render(in: context)
            
            // 将当前位置的像素值累加到总值上
            if pixel[0] != 0 && pixel[1] != 0 && pixel[2] != 0 {
                totalRed += CGFloat(pixel[0])
                totalGreen += CGFloat(pixel[1])
                totalBlue += CGFloat(pixel[2])
            } else {
                removeCount += 1
            }
        }
        
        // 计算平均颜色的分量值
        let count = CGFloat(positions.count - removeCount)
        let averageRed = totalRed / count
        let averageGreen = totalGreen / count
        let averageBlue = totalBlue / count
        
        // 创建并返回新的颜色
        return UIColor(red: averageRed / 255.0,
                       green: averageGreen / 255.0,
                       blue: averageBlue / 255.0,
                       alpha: 1.0)
    }

    /**
     *  将图层旋转radian弧度
     *
     *  @param radian 旋转的弧度
     */
    func rotate(by radian: CGFloat) {
        var transform = base.layer.affineTransform()
        transform = transform.rotated(by: radian)
        base.layer.setAffineTransform(transform)
    }

    
}

extension UIView {
    
    /// 添加点击事件
    /// - Parameter action: 点击
    public func addTapAction(action: (() -> Void)?) {
        tapAction = action
        isUserInteractionEnabled = true
        let selector = #selector(handleTap)
        let recognizer = UITapGestureRecognizer(target: self, action: selector)
        addGestureRecognizer(recognizer)
    }
    
    typealias Action = (() -> Void)
    
    struct Key { static var id = "tapAction" }
    
    var tapAction: Action? {
        get {
            return objc_getAssociatedObject(self, &Key.id) as? Action
        }
        set {
            guard let value = newValue else { return }
            let policy = objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN
            objc_setAssociatedObject(self, &Key.id, value, policy)
        }
    }
    
    @objc func handleTap(sender: UITapGestureRecognizer) {
        tapAction?()
    }
    
    
    // MARK: - 方便加载 nib 文件
    public class func fromNib<T: UIView>(_ bundleId: String? = nil) -> T {
        let className: String = self.className
        if bundleId != nil {
            let bundle = Bundle(identifier: bundleId!)
            return UINib.init(nibName: className, bundle: bundle).instantiate(withOwner: self, options: nil).last as! T
        }
        let v: T? = UINib.init(nibName: className, bundle: nil).instantiate(withOwner: self, options: nil).last as? T
        if v != nil {
            return v!
        }
        return T()
    }
    
    public class func fromBundle<T: UIView>(_ bundleId: String? = nil) -> T {
        let className: String = self.className
        if bundleId != nil {
            let bundle = Bundle(identifier: bundleId!)
            let t: T = (bundle?.loadNibNamed(className, owner: nil, options
                : nil)?.first as? T)!
            return t
        }
        let v: T? = Bundle.main.loadNibNamed(className, owner: nil, options: nil)?.first as? T
        if v != nil {
            return v!
        }
        return T()
    }
    
    public class func view<T: UIView>(with text: String, font: UIFont? = nil, color: UIColor? = nil) -> T {
        let lbl: UILabel = UILabel()
        if font != nil {
            lbl.font = font!
        }
        if color != nil {
            lbl.textColor = color!
        }
        lbl.text = text
        lbl.sizeToFit()
        return lbl as! T
    }
    
}
